Draw arrows better (without extra baseline)
authorSoeren Sandmann <sandmann@daimi.au.dk>
Tue, 26 Feb 2002 23:50:14 +0000 (23:50 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Tue, 26 Feb 2002 23:50:14 +0000 (23:50 +0000)
Wed Feb 27 00:45:39 2002  Soeren Sandmann  <sandmann@daimi.au.dk>

* gtk/gtkarrow.c, gtk/gtkmenuitem.c, gtk/gtkrange.c
gtk/gtkspinbutton.c gtk/gtkstyle.c: Draw arrows better (without
extra baseline)

12 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkarrow.c
gtk/gtkmenuitem.c
gtk/gtkrange.c
gtk/gtkspinbutton.c
gtk/gtkstyle.c

index 8dd432278c992f903eb56588a0a762b483e9a643..a42c115da8837ac83234313318c5c0b58baabafd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Wed Feb 27 00:45:39 2002  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * gtk/gtkarrow.c, gtk/gtkmenuitem.c, gtk/gtkrange.c
+       gtk/gtkspinbutton.c gtk/gtkstyle.c: Draw arrows better (without
+       extra baseline)
+
 Tue Feb 26 18:38:17 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkaccellabel.c (gtk_accel_label_refetch): 
index 8dd432278c992f903eb56588a0a762b483e9a643..a42c115da8837ac83234313318c5c0b58baabafd 100644 (file)
@@ -1,3 +1,9 @@
+Wed Feb 27 00:45:39 2002  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * gtk/gtkarrow.c, gtk/gtkmenuitem.c, gtk/gtkrange.c
+       gtk/gtkspinbutton.c gtk/gtkstyle.c: Draw arrows better (without
+       extra baseline)
+
 Tue Feb 26 18:38:17 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkaccellabel.c (gtk_accel_label_refetch): 
index 8dd432278c992f903eb56588a0a762b483e9a643..a42c115da8837ac83234313318c5c0b58baabafd 100644 (file)
@@ -1,3 +1,9 @@
+Wed Feb 27 00:45:39 2002  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * gtk/gtkarrow.c, gtk/gtkmenuitem.c, gtk/gtkrange.c
+       gtk/gtkspinbutton.c gtk/gtkstyle.c: Draw arrows better (without
+       extra baseline)
+
 Tue Feb 26 18:38:17 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkaccellabel.c (gtk_accel_label_refetch): 
index 8dd432278c992f903eb56588a0a762b483e9a643..a42c115da8837ac83234313318c5c0b58baabafd 100644 (file)
@@ -1,3 +1,9 @@
+Wed Feb 27 00:45:39 2002  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * gtk/gtkarrow.c, gtk/gtkmenuitem.c, gtk/gtkrange.c
+       gtk/gtkspinbutton.c gtk/gtkstyle.c: Draw arrows better (without
+       extra baseline)
+
 Tue Feb 26 18:38:17 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkaccellabel.c (gtk_accel_label_refetch): 
index 8dd432278c992f903eb56588a0a762b483e9a643..a42c115da8837ac83234313318c5c0b58baabafd 100644 (file)
@@ -1,3 +1,9 @@
+Wed Feb 27 00:45:39 2002  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * gtk/gtkarrow.c, gtk/gtkmenuitem.c, gtk/gtkrange.c
+       gtk/gtkspinbutton.c gtk/gtkstyle.c: Draw arrows better (without
+       extra baseline)
+
 Tue Feb 26 18:38:17 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkaccellabel.c (gtk_accel_label_refetch): 
index 8dd432278c992f903eb56588a0a762b483e9a643..a42c115da8837ac83234313318c5c0b58baabafd 100644 (file)
@@ -1,3 +1,9 @@
+Wed Feb 27 00:45:39 2002  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * gtk/gtkarrow.c, gtk/gtkmenuitem.c, gtk/gtkrange.c
+       gtk/gtkspinbutton.c gtk/gtkstyle.c: Draw arrows better (without
+       extra baseline)
+
 Tue Feb 26 18:38:17 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkaccellabel.c (gtk_accel_label_refetch): 
index 8dd432278c992f903eb56588a0a762b483e9a643..a42c115da8837ac83234313318c5c0b58baabafd 100644 (file)
@@ -1,3 +1,9 @@
+Wed Feb 27 00:45:39 2002  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * gtk/gtkarrow.c, gtk/gtkmenuitem.c, gtk/gtkrange.c
+       gtk/gtkspinbutton.c gtk/gtkstyle.c: Draw arrows better (without
+       extra baseline)
+
 Tue Feb 26 18:38:17 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkaccellabel.c (gtk_accel_label_refetch): 
index 5ce6b7eb31e7f532c173c48b1310a6af5d86aba1..bdf9b376cf1ff48e20846a78a24d036070670822 100644 (file)
@@ -241,13 +241,13 @@ gtk_arrow_expose (GtkWidget      *widget,
 
       width = widget->allocation.width - misc->xpad * 2;
       height = widget->allocation.height - misc->ypad * 2;
-      extent = MIN (width, height);
+      extent = MIN (width, height) * 0.7;
 
       if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
        xalign = misc->xalign;
       else
        xalign = 1.0 - misc->xalign;
-  
+
       x = floor (widget->allocation.x + misc->xpad
                 + ((widget->allocation.width - extent) * xalign)
                 + 0.5);
index 6b22ca714be60a6982631ef2daf55998db82ff38..7185df8e7333277f97a2ae2b83afa7700de9df01 100644 (file)
@@ -458,10 +458,10 @@ gtk_menu_item_size_request (GtkWidget      *widget,
 
       requisition->width += child_requisition.width;
       requisition->height += child_requisition.height;
-    }
 
-  if (menu_item->submenu && menu_item->show_submenu_indicator)
-    requisition->width += 21;
+      if (menu_item->submenu && menu_item->show_submenu_indicator)
+       requisition->width += child_requisition.height;
+    }
 
   accel_width = 0;
   gtk_container_foreach (GTK_CONTAINER (menu_item),
@@ -501,8 +501,8 @@ gtk_menu_item_size_allocate (GtkWidget     *widget,
       child_allocation.y += widget->allocation.y;
       
       if (menu_item->submenu && menu_item->show_submenu_indicator)
-       child_allocation.width -= 21;
-      
+       child_allocation.width -= child_allocation.height;
+
       gtk_widget_size_allocate (bin->child, &child_allocation);
     }
 
@@ -614,22 +614,30 @@ gtk_menu_item_paint (GtkWidget    *widget,
 
       if (menu_item->submenu && menu_item->show_submenu_indicator)
        {
+         gint arrow_x, arrow_y;
+         gint arrow_size = height - 2 * widget->style->ythickness;
+         gint arrow_extent = arrow_size / 2;
+         
          shadow_type = GTK_SHADOW_OUT;
          if (state_type == GTK_STATE_PRELIGHT)
            shadow_type = GTK_SHADOW_IN;
 
+         arrow_x = x + width - 1 - arrow_size + (arrow_size - arrow_extent) / 2;
+         arrow_y = y + (height - arrow_extent) / 2;
+
          gtk_paint_arrow (widget->style, widget->window,
                           state_type, shadow_type, 
                           area, widget, "menuitem", 
                           GTK_ARROW_RIGHT, TRUE,
-                          x + width - 15, y + height / 2 - 5, 10, 10);
+                          arrow_x, arrow_y,
+                          arrow_extent, arrow_extent);
        }
       else if (!GTK_BIN (menu_item)->child)
        {
-          gtk_paint_hline (widget->style, widget->window, GTK_STATE_NORMAL,
-                           area, widget, "menuitem",
-                           widget->allocation.x, widget->allocation.width,
-                           widget->allocation.y);
+         gtk_paint_hline (widget->style, widget->window, GTK_STATE_NORMAL,
+                          area, widget, "menuitem",
+                          widget->allocation.x, widget->allocation.width,
+                          widget->allocation.y);
        }
     }
 }
index 2007fae409961c04f9cd67e02941ef5aa9596234..a7dea7a63b4d211331cf5ed0681c8f486a6af4b5 100644 (file)
@@ -143,7 +143,9 @@ static void          gtk_range_get_props                (GtkRange      *range,
                                                          gint          *slider_width,
                                                          gint          *stepper_size,
                                                          gint          *trough_border,
-                                                         gint          *stepper_spacing);
+                                                         gint          *stepper_spacing,
+                                                        gint          *arrow_displacement_x,
+                                                        gint          *arrow_displacement_y);
 static void          gtk_range_calc_request             (GtkRange      *range,
                                                          gint           slider_width,
                                                          gint           stepper_size,
@@ -322,6 +324,22 @@ gtk_range_class_init (GtkRangeClass *class)
                                                             G_MAXINT,
                                                             0,
                                                             G_PARAM_READABLE));
+  gtk_widget_class_install_style_property (widget_class,
+                                          g_param_spec_int ("arrow_displacement_x",
+                                                            _("Arrow X Displacement"),
+                                                            _("How far in the x direction to move the arrow when the button is depressed"),
+                                                            G_MININT,
+                                                            G_MAXINT,
+                                                            0,
+                                                            G_PARAM_READABLE));
+  gtk_widget_class_install_style_property (widget_class,
+                                          g_param_spec_int ("arrow_displacement_y",
+                                                            _("Arrow Y Displacement"),
+                                                            _("How far in the y direction to move the arrow when the button is depressed"),
+                                                            G_MININT,
+                                                            G_MAXINT,
+                                                            0,
+                                                            G_PARAM_READABLE));
 }
 
 static void
@@ -710,7 +728,8 @@ gtk_range_size_request (GtkWidget      *widget,
   range = GTK_RANGE (widget);
   
   gtk_range_get_props (range,
-                       &slider_width, &stepper_size, &trough_border, &stepper_spacing);
+                       &slider_width, &stepper_size, &trough_border, &stepper_spacing,
+                      NULL, NULL);
 
   gtk_range_calc_request (range, 
                           slider_width, stepper_size, trough_border, stepper_spacing,
@@ -834,6 +853,11 @@ draw_stepper (GtkRange     *range,
   GdkRectangle intersection;
   GtkWidget *widget = GTK_WIDGET (range);
 
+  gint arrow_x;
+  gint arrow_y;
+  gint arrow_width;
+  gint arrow_height;
+
   /* More to get the right clip region than for efficiency */
   if (!gdk_rectangle_intersect (area, rect, &intersection))
     return;
@@ -854,17 +878,42 @@ draw_stepper (GtkRange     *range,
     shadow_type = GTK_SHADOW_IN;
   else
     shadow_type = GTK_SHADOW_OUT;
+
+  gtk_paint_box (widget->style,
+                widget->window,
+                state_type, shadow_type,
+                &intersection, widget,
+                GTK_RANGE_GET_CLASS (range)->stepper_detail,
+                widget->allocation.x + rect->x,
+                widget->allocation.y + rect->y,
+                rect->width,
+                rect->height);
+
+  arrow_width = rect->width / 2;
+  arrow_height = rect->height / 2;
+  arrow_x = widget->allocation.x + rect->x + (rect->width - arrow_width) / 2;
+  arrow_y = widget->allocation.y + rect->y + (rect->height - arrow_height) / 2;
   
-  gtk_paint_arrow (GTK_WIDGET (range)->style,
-                   GTK_WIDGET (range)->window,
+  if (clicked)
+    {
+      gint arrow_displacement_x;
+      gint arrow_displacement_y;
+
+      gtk_range_get_props (GTK_RANGE (widget), NULL, NULL, NULL, NULL,
+                          &arrow_displacement_x, &arrow_displacement_y);
+      
+      arrow_x += arrow_displacement_x;
+      arrow_y += arrow_displacement_y;
+    }
+  
+  gtk_paint_arrow (widget->style,
+                   widget->window,
                    state_type, shadow_type, 
-                   &intersection, GTK_WIDGET (range),
+                   &intersection, widget,
                    GTK_RANGE_GET_CLASS (range)->stepper_detail,
                    arrow_type,
                    TRUE,
-                  widget->allocation.x + rect->x,
-                  widget->allocation.y + rect->y,
-                  rect->width, rect->height);
+                  arrow_x, arrow_y, arrow_width, arrow_height);
 }
 
 static gint
@@ -1562,16 +1611,21 @@ gtk_range_get_props (GtkRange  *range,
                      gint      *slider_width,
                      gint      *stepper_size,
                      gint      *trough_border,
-                     gint      *stepper_spacing)
+                     gint      *stepper_spacing,
+                    gint      *arrow_displacement_x,
+                    gint      *arrow_displacement_y)
 {
   GtkWidget *widget =  GTK_WIDGET (range);
   gint tmp_slider_width, tmp_stepper_size, tmp_trough_border, tmp_stepper_spacing;
+  gint tmp_arrow_displacement_x, tmp_arrow_displacement_y;
   
   gtk_widget_style_get (widget,
                         "slider_width", &tmp_slider_width,
                         "trough_border", &tmp_trough_border,
                         "stepper_size", &tmp_stepper_size,
                         "stepper_spacing", &tmp_stepper_spacing,
+                       "arrow_displacement_x", &tmp_arrow_displacement_x,
+                       "arrow_displacement_y", &tmp_arrow_displacement_y,
                         NULL);
   
   if (slider_width)
@@ -1585,6 +1639,12 @@ gtk_range_get_props (GtkRange  *range,
 
   if (stepper_spacing)
     *stepper_spacing = tmp_stepper_spacing;
+
+  if (arrow_displacement_x)
+    *arrow_displacement_x = tmp_arrow_displacement_x;
+
+  if (arrow_displacement_y)
+    *arrow_displacement_y = tmp_arrow_displacement_y;
 }
 
 #define POINT_IN_RECT(xcoord, ycoord, rect) \
@@ -1812,7 +1872,8 @@ gtk_range_calc_layout (GtkRange *range,
   layout = range->layout;
   
   gtk_range_get_props (range,
-                       &slider_width, &stepper_size, &trough_border, &stepper_spacing);
+                       &slider_width, &stepper_size, &trough_border, &stepper_spacing,
+                      NULL, NULL);
 
   gtk_range_calc_request (range, 
                           slider_width, stepper_size, trough_border, stepper_spacing,
index ea5cc8cd6da9f685cd7583cbff55c86e89537555..ae1a0208afcce1f463edbb2befd4f50ac529c794 100644 (file)
@@ -111,7 +111,7 @@ static void gtk_spin_button_grab_notify    (GtkWidget          *widget,
 static void gtk_spin_button_state_changed  (GtkWidget          *widget,
                                            GtkStateType        previous_state);
 static void gtk_spin_button_draw_arrow     (GtkSpinButton      *spin_button, 
-                                           guint               arrow);
+                                           GtkArrowType        arrow_type);
 static gint gtk_spin_button_timer          (GtkSpinButton      *spin_button);
 static void gtk_spin_button_stop_spinning  (GtkSpinButton      *spin);
 static void gtk_spin_button_value_changed  (GtkAdjustment      *adjustment,
@@ -783,17 +783,17 @@ spin_button_at_limit (GtkSpinButton *spin_button,
   if (arrow == GTK_ARROW_UP &&
       (spin_button->adjustment->upper - spin_button->adjustment->value <= EPSILON))
     return TRUE;
-
+  
   if (arrow == GTK_ARROW_DOWN &&
       (spin_button->adjustment->value - spin_button->adjustment->lower <= EPSILON))
     return TRUE;
-
+  
   return FALSE;
 }
 
 static void
 gtk_spin_button_draw_arrow (GtkSpinButton *spin_button, 
-                           guint          arrow)
+                           GtkArrowType   arrow_type)
 {
   GtkStateType state_type;
   GtkShadowType shadow_type;
@@ -802,9 +802,10 @@ gtk_spin_button_draw_arrow (GtkSpinButton *spin_button,
   gint y;
   gint height;
   gint width;
+  gint h, w;
 
   g_return_if_fail (GTK_IS_SPIN_BUTTON (spin_button));
-  g_return_if_fail (arrow == GTK_ARROW_UP || arrow == GTK_ARROW_DOWN);
+  g_return_if_fail (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN);
   
   widget = GTK_WIDGET (spin_button);
 
@@ -812,7 +813,7 @@ gtk_spin_button_draw_arrow (GtkSpinButton *spin_button,
     {
       width = spin_button_get_arrow_size (spin_button) + 2 * widget->style->xthickness;
 
-      if (arrow == GTK_ARROW_UP)
+      if (arrow_type == GTK_ARROW_UP)
        {
          x = 0;
          y = 0;
@@ -827,21 +828,21 @@ gtk_spin_button_draw_arrow (GtkSpinButton *spin_button,
          height = (widget->requisition.height + 1) / 2;
        }
 
-      if (spin_button_at_limit (spin_button, arrow))
+      if (spin_button_at_limit (spin_button, arrow_type))
        {
          shadow_type = GTK_SHADOW_OUT;
          state_type = GTK_STATE_INSENSITIVE;
        }
       else
        {
-         if (spin_button->click_child == arrow)
+         if (spin_button->click_child == arrow_type)
            {
              state_type = GTK_STATE_ACTIVE;
              shadow_type = GTK_SHADOW_IN;
            }
          else
            {
-             if (spin_button->in_child == arrow &&
+             if (spin_button->in_child == arrow_type &&
                  spin_button->click_child == NO_ARROW)
                {
                  state_type = GTK_STATE_PRELIGHT;
@@ -858,17 +859,44 @@ gtk_spin_button_draw_arrow (GtkSpinButton *spin_button,
       gtk_paint_box (widget->style, spin_button->panel,
                     state_type, shadow_type,
                     NULL, widget,
-                    (arrow == GTK_ARROW_UP)? "spinbutton_up" : "spinbutton_down",
+                    (arrow_type == GTK_ARROW_UP)? "spinbutton_up" : "spinbutton_down",
                     x, y, width, height);
 
+      height = widget->requisition.height;
+
+      if (arrow_type == GTK_ARROW_DOWN)
+       {
+         y = height / 2;
+         height = height - y - 2;
+       }
+      else
+       {
+         y = 2;
+         height = height / 2 - 2;
+       }
+
+      width -= 3;
+
+      if (widget && gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+       x = 2;
+      else
+       x = 1;
+
+      w = width / 2;
+      w -= w % 2 - 1; /* force odd */
+      h = (w + 1) / 2;
+      
+      x += (width - w) / 2;
+      y += (height - h) / 2;
+      
+      height = h;
+      width = w;
+
       gtk_paint_arrow (widget->style, spin_button->panel,
                       state_type, shadow_type, 
                       NULL, widget, "spinbutton",
-                      arrow, TRUE, 
-                      x + widget->style->xthickness,
-                      y + widget->style->ythickness,
-                      width - 2 * widget->style->xthickness,
-                      (widget->requisition.height + 1) / 2 - 2 * widget->style->ythickness);
+                      arrow_type, TRUE, 
+                      x, y, width, height);
     }
 }
 
@@ -1290,7 +1318,7 @@ gtk_spin_button_snap (GtkSpinButton *spin_button,
 {
   gdouble inc;
   gdouble tmp;
-  
+
   inc = spin_button->adjustment->step_increment;
   tmp = (val - spin_button->adjustment->lower) / inc;
   if (tmp - floor (tmp) < ceil (tmp) - tmp)
index beef9abb4dff4d094b3a0cddab8eb7763d8893ae..30104c4413ffeaec5ef2c1a22ee1fb524df85699 100644 (file)
@@ -2774,109 +2774,112 @@ gtk_default_draw_polygon (GtkStyle      *style,
 }
 
 static void
-draw_varrow (GdkWindow     *window,
-            GdkGC         *gc,
-            GtkShadowType  shadow_type,
-            GdkRectangle  *area,
-            GtkArrowType   arrow_type,
-            gint           x,
-            gint           y,
-            gint           width,
-            gint           height)
+draw_arrow (GdkWindow     *window,
+           GdkGC         *gc,
+           GdkRectangle  *area,
+           GtkArrowType   arrow_type,
+           gint           x,
+           gint           y,
+           gint           width,
+           gint           height)
 {
-  gint steps, extra;
-  gint y_start, y_increment;
-  gint i;
+  gint i, j;
 
   if (area)
     gdk_gc_set_clip_rectangle (gc, area);
-  
-  width = width + width % 2 - 1;       /* Force odd */
-  
-  steps = 1 + width / 2;
-
-  extra = height - steps;
 
   if (arrow_type == GTK_ARROW_DOWN)
     {
-      y_start = y;
-      y_increment = 1;
+      for (i = 0, j = 0; i < height; i++, j++)
+       gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
     }
-  else
+  else if (arrow_type == GTK_ARROW_UP)
     {
-      y_start = y + height - 1;
-      y_increment = -1;
+      for (i = height - 1, j = 0; i >= 0; i--, j++)
+       gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
     }
-
-  for (i = 0; i < extra; i++)
+  else if (arrow_type == GTK_ARROW_LEFT)
     {
-      gdk_draw_line (window, gc,
-                    x,              y_start + i * y_increment,
-                    x + width - 1,  y_start + i * y_increment);
+      for (i = width - 1, j = 0; i >= 0; i--, j++)
+       gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
     }
-  for (; i < height; i++)
+  else if (arrow_type == GTK_ARROW_RIGHT)
     {
-      gdk_draw_line (window, gc,
-                    x + (i - extra),              y_start + i * y_increment,
-                    x + width - (i - extra) - 1,  y_start + i * y_increment);
+      for (i = 0, j = 0; i < width; i++, j++)
+       gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
     }
-  
 
   if (area)
     gdk_gc_set_clip_rectangle (gc, NULL);
 }
 
 static void
-draw_harrow (GdkWindow     *window,
-            GdkGC         *gc,
-            GtkShadowType  shadow_type,
-            GdkRectangle  *area,
-            GtkArrowType   arrow_type,
-            gint           x,
-            gint           y,
-            gint           width,
-            gint           height)
+calculate_arrow_geometry (GtkArrowType  arrow_type,
+                         gint         *x,
+                         gint         *y,
+                         gint         *width,
+                         gint         *height)
 {
-  gint steps, extra;
-  gint x_start, x_increment;
-  gint i;
-
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, area);
+  gint w = *width;
+  gint h = *height;
   
-  height = height + height % 2 - 1;    /* Force odd */
-  
-  steps = 1 + height / 2;
-
-  extra = width - steps;
-
-  if (arrow_type == GTK_ARROW_RIGHT)
-    {
-      x_start = x;
-      x_increment = 1;
-    }
-  else
+  switch (arrow_type)
     {
-      x_start = x + width - 1;
-      x_increment = -1;
-    }
+    case GTK_ARROW_UP:
+    case GTK_ARROW_DOWN:
+      w += (w % 2) - 1;
+      h = (w / 2 + 1);
+      
+      if (h > *height)
+       {
+         h = *height;
+         w = 2 * h - 1;
+       }
+      
+      if (arrow_type == GTK_ARROW_DOWN)
+       {
+         if (*height % 2 == 1 || h % 2 == 0)
+           *height += 1;
+       }
+      else
+       {
+         if (*height % 2 == 0 || h % 2 == 0)
+           *height -= 1;
+       }
+      break;
 
-  for (i = 0; i < extra; i++)
-    {
-      gdk_draw_line (window, gc,
-                    x_start + i * x_increment, y,
-                    x_start + i * x_increment, y + height - 1);
-    }
-  for (; i < width; i++)
-    {
-      gdk_draw_line (window, gc,
-                    x_start + i * x_increment, y + (i - extra),
-                    x_start + i * x_increment, y + height - (i - extra) - 1);
+    case GTK_ARROW_RIGHT:
+    case GTK_ARROW_LEFT:
+      h += (h % 2) - 1;
+      w = (h / 2 + 1);
+      
+      if (w > *width)
+       {
+         w = *width;
+         h = 2 * w - 1;
+       }
+      
+      if (arrow_type == GTK_ARROW_RIGHT)
+       {
+         if (*width % 2 == 1 || w % 2 == 0)
+           *width += 1;
+       }
+      else
+       {
+         if (*width % 2 == 0 || w % 2 == 0)
+           *width -= 1;
+       }
+      break;
+      
+    default:
+      /* should not be reached */
+      break;
     }
-  
 
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, NULL);
+  *x += (*width - w) / 2;
+  *y += (*height - h) / 2;
+  *height = h;
+  *width = w;
 }
 
 static void
@@ -2894,77 +2897,23 @@ gtk_default_draw_arrow (GtkStyle      *style,
                        gint           width,
                        gint           height)
 {
-  sanitize_size (window, &width, &height);
+  gint original_width, original_x;
   
-  if (detail && strcmp (detail, "spinbutton") == 0)
-    {
-      int hpad, vpad;
-      int my_height = height;
-      int my_width = width;
-      int vpad_add = 0;
-
-      if (my_height > my_width)
-       {
-         vpad_add = (my_height - my_width) / 2;
-         my_height = my_width;
-       }
-
-      hpad = my_width / 4;
-
-      if (hpad < 4)
-       hpad = 4;
-
-      vpad = 2 * hpad - 1;
-
-      x += hpad / 2;
-      y += vpad / 2;
+  sanitize_size (window, &width, &height);
 
-      y += vpad_add;
+  original_width = width;
+  original_x = x;
 
-      draw_varrow (window, style->fg_gc[state], shadow, area, arrow_type,
-                  x, y, my_width - hpad, my_height - vpad);
-    }
-  else if (detail && strcmp (detail, "vscrollbar") == 0)
-    {
-      gtk_paint_box (style, window, state, shadow, area,
-                    widget, detail, x, y, width, height);
-      
-      x += (width - 7) / 2;
-      y += (height - 5) / 2;
-      
-      draw_varrow (window, style->fg_gc[state], shadow, area, arrow_type,
-                  x, y, 7, 5);
-    }
-  else if (detail && strcmp (detail, "hscrollbar") == 0)
-    {
-      gtk_paint_box (style, window, state, shadow, area,
-                    widget, detail, x, y, width, height);
-      
-      y += (height - 7) / 2;
-      x += (width - 5) / 2;
+  calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
+  
+  if (detail && strcmp (detail, "menuitem") == 0)
+    x = original_x + original_width - width;
 
-      draw_harrow (window, style->fg_gc[state], shadow, area, arrow_type,
-                  x, y, 5, 7);
-    }
-  else
-    {
-      if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
-       {
-         x += (width - 7) / 2;
-         y += (height - 5) / 2;
-         
-         draw_varrow (window, style->fg_gc[state], shadow, area, arrow_type,
-                      x, y, 7, 5);
-       }
-      else
-       {
-         x += (width - 5) / 2;
-         y += (height - 7) / 2;
-         
-         draw_harrow (window, style->fg_gc[state], shadow, area, arrow_type,
-                      x, y, 5, 7);
-       }
-    }
+  if (state == GTK_STATE_INSENSITIVE)
+    draw_arrow (window, style->white_gc, area, arrow_type,
+               x + 1, y + 1, width, height);
+  draw_arrow (window, style->fg_gc[state], area, arrow_type,
+             x, y, width, height);
 }
 
 static void
@@ -3468,7 +3417,7 @@ gtk_default_draw_check (GtkStyle      *style,
          GdkGC *base_gc = style->base_gc[state_type];
 
          if (state_type == GTK_STATE_ACTIVE)
-           base_gc = style->bg_gc[state_type];
+           base_gc = style->bg_gc[GTK_STATE_ACTIVE];
          
          draw_part (window, base_gc, area, x, y, CHECK_BASE);
          draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
@@ -3548,7 +3497,7 @@ gtk_default_draw_option (GtkStyle      *style,
          GdkGC *base_gc = style->base_gc[state_type];
 
          if (state_type == GTK_STATE_ACTIVE)
-           base_gc = style->bg_gc[state_type];
+           base_gc = style->bg_gc[GTK_STATE_ACTIVE];
 
          draw_part (window, base_gc, area, x, y, RADIO_BASE);
          draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
@@ -3582,18 +3531,39 @@ gtk_default_draw_tab (GtkStyle      *style,
                      gint           width,
                      gint           height)
 {
+#define ARROW_SPACE 4
+
   GtkRequisition indicator_size;
   GtkBorder indicator_spacing;
+  gint arrow_height;
   
   option_menu_get_props (widget, &indicator_size, &indicator_spacing);
 
+  indicator_size.width += (indicator_size.width % 2) - 1;
+  arrow_height = indicator_size.width / 2 + 1;
+
   x += (width - indicator_size.width) / 2;
-  y += (height - indicator_size.height) / 2 - 1;
+  y += (height - (2 * arrow_height + ARROW_SPACE)) / 2;
 
-  draw_varrow (window, style->black_gc, shadow_type, area, GTK_ARROW_UP,
-              x, y, indicator_size.width, 5);
-  draw_varrow (window, style->black_gc, shadow_type, area, GTK_ARROW_DOWN,
-              x, y + 8, indicator_size.width, 5);
+  if (state_type == GTK_STATE_INSENSITIVE)
+    {
+      draw_arrow (window, style->white_gc, area,
+                 GTK_ARROW_UP, x + 1, y + 1,
+                 indicator_size.width, arrow_height);
+      
+      draw_arrow (window, style->white_gc, area,
+                 GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
+                 indicator_size.width, arrow_height);
+    }
+  
+  draw_arrow (window, style->fg_gc[state_type], area,
+             GTK_ARROW_UP, x, y,
+             indicator_size.width, arrow_height);
+  
+  
+  draw_arrow (window, style->fg_gc[state_type], area,
+             GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
+             indicator_size.width, arrow_height);
 }
 
 static void